import { Request, Response, NextFunction } from 'express';
import { prisma } from '../config/database';
import { logger } from '../utils/logger';

export interface OperationLogData {
  action: string;
  resource: string;
  resourceId?: string | undefined;
  details?: any;
  skipLog?: boolean;
}

declare global {
  namespace Express {
    interface Request {
      operationLog?: OperationLogData;
    }
  }
}

/**
 * 操作日志记录中间件
 * 使用方法：
 * 1. 在路由中设置 req.operationLog = { action: '操作名称', resource: '资源类型', resourceId: '资源ID', details: {} }
 * 2. 中间件会自动记录操作日志
 */
export const operationLogMiddleware = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
  const originalSend = res.send;
  
  res.send = function(data) {
    // 恢复原始的send方法
    res.send = originalSend;
    
    // 记录操作日志
    recordOperationLog(req, res, data);
    
    // 调用原始的send方法
    return originalSend.call(this, data);
  };
  
  next();
};

/**
 * 记录操作日志
 */
async function recordOperationLog(req: Request, res: Response, responseData: any): Promise<void> {
  try {
    // 如果没有设置操作日志数据，跳过记录
    if (!req.operationLog || req.operationLog.skipLog) {
      return;
    }

    const { action, resource, resourceId, details } = req.operationLog;
    
    // 获取用户信息
    const userId = (req as any).user?.id;
    
    // 获取IP地址
    const ipAddress = req.ip || req.connection.remoteAddress || req.headers['x-forwarded-for'] || 'unknown';
    
    // 获取用户代理
    const userAgent = req.headers['user-agent'] || '';
    
    // 构建日志详情
    const logDetails = {
      ...details,
      method: req.method,
      url: req.originalUrl,
      params: req.params,
      query: req.query,
      body: req.body,
      responseStatus: res.statusCode,
      responseData: responseData
    };

    // 创建操作日志记录
    await prisma.operationLog.create({
      data: {
        userId: userId || null,
        action,
        resource,
        resourceId: resourceId || null,
        details: logDetails,
        ipAddress: Array.isArray(ipAddress) ? ipAddress[0] : ipAddress,
        userAgent
      }
    });

    logger.info(`操作日志记录: ${action} - ${resource}${resourceId ? ` (ID: ${resourceId})` : ''} - 用户: ${userId || '匿名'}`);
  } catch (error) {
    logger.error('记录操作日志失败:', error);
  }
}

/**
 * 操作日志装饰器 - 用于简化控制器中的日志记录
 */
export const logOperation = (action: string, resource: string, getResourceId?: (req: Request) => string, getDetails?: (req: Request) => any) => {
  return (req: Request, _res: Response, next: NextFunction): void => {
    req.operationLog = {
      action,
      resource,
      resourceId: getResourceId ? getResourceId(req) : undefined,
      details: getDetails ? getDetails(req) : undefined
    };
    next();
  };
};

/**
 * 跳过日志记录装饰器
 */
export const skipLog = (req: Request, _res: Response, next: NextFunction): void => {
  req.operationLog = { action: '', resource: '', skipLog: true };
  next();
}; 